/*
 * AccountManager.java
 *
 * Distributed Systems: Project 2
 *
 */

package unimelb.distSystems.communications;

import unimelb.distSystems.communications.CORBA.*;
import unimelb.distSystems.project2.Configurations;

import java.io.*;
import java.util.*;


public class AccountManager {
    private static String filePath = Configurations.server_data_filepath;
    private List accounts;

    public AccountManager(){
        accounts = new ArrayList();
        readAccountsFile();
    }


    public final void readAccountsFile(){
        File file = null;
        FileInputStream fis = null;
        ObjectInputStream oin = null;

        try {
            file = new File(filePath);
            if(!file.exists()){
                file.createNewFile();
                accounts = new ArrayList();
                return;
            }

            fis = new FileInputStream(file);

            if(fis.available() == 0){
                return;
            }

            oin = new ObjectInputStream(fis);
            accounts = (ArrayList) oin.readObject();

        } catch (FileNotFoundException e) {
            System.out.println("ERROR reading the Accounts fle.");
            System.out.println(e.getMessage());
        } catch (IOException e) {
            System.out.println("ERROR reading the Accounts file.");
            System.out.println(e.getMessage());
        } catch(Exception e){
            System.out.println("ERROR reading the Accounts file.");
            e.printStackTrace();
        }finally{
            if (fis != null) {
                try {
                    fis.close();
                } catch(Exception ex) {}
            }
            if (oin != null) {
                try {
                    oin.close();
                } catch(Exception ex) {}
            }
        }
    }

    public final void saveAccountsFile(){
        File file = null;
        FileOutputStream fos = null;
        ObjectOutputStream out = null;

        try {
            file = new File(filePath);
            fos = new FileOutputStream(file);

            out = new ObjectOutputStream(fos);
            out.writeObject(accounts);

        } catch (FileNotFoundException e) {
            System.out.println("ERROR reading the Accounts fle.");
            System.out.println(e.getMessage());
        } catch (IOException e) {
            System.out.println("ERROR reading the Accounts file.");
            System.out.println(e.getMessage());
        } catch(Exception e){
            System.out.println("ERROR reading the Accounts file.");
            System.out.println(e.getMessage());
        }finally{
            if (fos != null) {
                try {
                    fos.close();
                } catch(Exception ex) {}
            }
            if (out != null) {
                try {
                    out.close();
                } catch(Exception ex) {}
            }
        }
    }


    // Validates if a user already exists
    public boolean exists(String username){
        ListIterator li = accounts.listIterator();

        while(li.hasNext()){
            UserAccount a = (UserAccount)li.next();
            if(a.getUsername().equals(username)){
                return true;
            }
        }
        return false;
    }

    // Validates if a user's id already exists
    public boolean validateID(long id){
        ListIterator li = accounts.listIterator();

        while(li.hasNext()){
            UserAccount a = (UserAccount)li.next();
            if(a.getUserID() == id){
                return false;
            }
        }
        return true;
    }

    // Login User
    public ServiceAccount login(ClientService callback, String username, String password){
        ListIterator li = accounts.listIterator();

        while(li.hasNext()){
            UserAccount a = (UserAccount)li.next();
            if(a.getUsername().equals(username)){
                if(a.getPassword().equals(password)){
                    a.setCallback(callback);
                    return a.getAccount();
                }
            }
        }
        return null;
    }

    public ServiceAccount getUser(long id){
        ListIterator li = accounts.listIterator();

        while(li.hasNext()){
            UserAccount a = (UserAccount)li.next();
            if(a.getUserID() == id){
                return a.getAccount();
            }
        }
        return null;
    }

    public UserAccount getUserAccount(long id){
        ListIterator li = accounts.listIterator();

        while(li.hasNext()){
            UserAccount a = (UserAccount)li.next();
            if(a.getUserID() == id){
                return a;
            }
        }
        return null;
    }

    public boolean logout(){
        return true;
    }

    public UserAccount addNewUser(ServiceAccount account){
        UserAccount newAccount = new UserAccount(account);
        if(!exists(newAccount.getUsername())){
            newAccount.generateID();
            while(!validateID(newAccount.getUserID())){
                newAccount.adjustID();
            }
            accounts.add(newAccount);
            saveAccountsFile();
        } else {
            return null;
        }
        return newAccount;
    }



}
